import { E_HumanState } from "../Test/Human/Human";
import { BaseState } from "./BaseState";
import { Translations } from "./Translations";

/**
 * 单层状态机
 * statesMap是所有状态的map，用enum枚举
 * translations是状态是否可转换的对象，如果为null则全部可以转换
 */
export class FSM {
    statesMap:Map<number, BaseState> = new Map();
    translations:Translations;

    constructor(statesMap: Map<number, BaseState>, translations:Translations=null) {
        this.statesMap = statesMap;
        this.translations = translations;
    }

    Start(e_index:number) {
        let startState:BaseState = this.GetState(e_index);
        this.currentState = startState;
    }

    Translate(e_index:number):boolean {
        let isOk:boolean = false;
        let to:BaseState = this.GetState(e_index);
        if (this.Pass(this.currentState.index, e_index)) {
            this.currentState = to;
            isOk = true;
        }
        return isOk;
    }

    Tick() {
        if (this.currentState) {
            this.currentState.OnUpdate();
        }
    }

    HasState(e_index:number):boolean {
        return this.statesMap.has(e_index);
    }

    GetState(e_index:number) {
        if (!this.HasState(e_index)) {
            console.error("状态机找不到状态");
        }
        return this.statesMap.get(e_index);
    }

    Pass(from_index:number, to_index:number):boolean {
        let pass = false;
        if (this.translations) {
            let from:BaseState = this.GetState(from_index);
            let to:BaseState = this.GetState(to_index);
            pass = this.translations.Pass(from, to);
        }
        else {
            pass = true;    //不传入translations则全部状态可切换
        }
        return pass;
    }

    private _currentState:BaseState;
    public get currentState():BaseState {
        return this._currentState;
    }
    public set currentState(value:BaseState) {
        if (this._currentState) {
            this._currentState.OnExit();
        }
        this.lastState = this._currentState;
        this._currentState = value;
        this._currentState.OnEnter();
    }

    private _lastState:BaseState;
    public get lastState():BaseState {
        return this._lastState;
    }
    public set lastState(value:BaseState) {
        this._lastState = value;
    }

}
